using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Lync.Widget.Library.Configuration;
using Lync.Widget.Library.ServiceHelpers;
using Lync.Widget.Library.UserService;

namespace Lync.Widget.Library.Repositories
{
    public sealed class ActiveDirectoryRepository : IActiveDirectoryRepository
    {
        #region Private Fields

        private IUserService m_UserServiceClient;
        public IUserService UserServiceClient
        {
            get { return m_UserServiceClient ?? (m_UserServiceClient = new UserServiceClient()); }
        }
        
        private IActiveDirectoryFieldMapper m_ActiveDirectoryFieldMapper;
        public IActiveDirectoryFieldMapper ActiveDirectoryFieldMapper
        {
            get { return m_ActiveDirectoryFieldMapper ?? (m_ActiveDirectoryFieldMapper = new ActiveDirectoryFieldMapper()); }
        }

        
        private IActiveDirectoryGroupConfiguration m_ActiveDirectoryGroupConfiguration;
        public IActiveDirectoryGroupConfiguration Configuration
        {
            get { return m_ActiveDirectoryGroupConfiguration ?? (m_ActiveDirectoryGroupConfiguration = ActiveDirectoryGroupConfigurationSection.Load()); }
        }

        #endregion


        #region Constructors

        public ActiveDirectoryRepository()            
        { }

        public ActiveDirectoryRepository(IUserService userServiceClient,
                                         IActiveDirectoryFieldMapper activeDirectoryFieldMapper,
                                         IActiveDirectoryGroupConfiguration activeDirectoryGroupConfiguration)
        {
            m_UserServiceClient = userServiceClient;
            m_ActiveDirectoryFieldMapper = activeDirectoryFieldMapper;
            m_ActiveDirectoryGroupConfiguration = activeDirectoryGroupConfiguration;
        }

        #endregion

        #region Public Methods

        public IList<User> GetUsers(string query, char separator = '+')
        {
            var filter = ActiveDirectoryFieldMapper.GetByQuery(query, separator);

            if (filter != null)
            {
                var users = GetUsers(filter);

                return users;    
            }

            return null;
        }

        public IList<User> GetUsers(User filter, char separator = '+')
        {
            var users = UserServiceClient.GetUsers(filter, separator);

            return users;
        }

        public IList<User>  GetUsersFromGroup(Group group)
        {
            var users = UserServiceClient.GetMembersOfGroup(group);
            
            return users;
        }

        public User GetUser(string sipUri, char separator = '+')
        {
            var users = GetUsers(new List<string> {sipUri}, separator);
            return users != null ? users.FirstOrDefault() : null;
        }

        public IList<User> GetUsers(List<string> sipUri, char separator = '+')
        {
            var filter = new User
                             {
                                 SipAddress = string.Join(separator.ToString(CultureInfo.InvariantCulture), sipUri),
                             };

            var users = UserServiceClient.GetUsers(filter, separator);
            return users != null ? users.ToList() : null;
        }
        
        public IList<Group> GetGroups()
        {
            var groups = UserServiceClient.GetDistributionGroups();

            return groups;
        }

        public IList<Group> GetGroups(string organisationUnit)
        {
            var groups = UserServiceClient.GetDistributionsGroupForUnit(organisationUnit);

            return groups;
        }

        public IList<IActiveDirectoryGroup> GetGroupsFromConfiguration()
        {
            return Configuration.Groups.ToList();
        }

        public IActiveDirectoryGroup GetGroupFromConfiguration(string groupId)
        {
            return Configuration.Groups.SingleOrDefault(group => group.Id == groupId);
        }

        #endregion

    }
}